package com.snjx.netty.chat.netty.server;

import com.snjx.netty.chat.netty.WebsocketServerChannelInitializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.FixedRecvByteBufAllocator;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @ClassName NettyServer
 * @Author yunlong.zhang
 * @Date 2018/11/13
 * @since: JDK 1.8
 * @Description //TODO
 **/
@Component
@Slf4j
public class NettyServer {
    private void startServer() {
        //服务端需要2个线程组  boss处理客户端连接  work进行客服端连接之后的处理
        EventLoopGroup bossGroup = new NioEventLoopGroup(10);
        EventLoopGroup workGroup = new NioEventLoopGroup(10);
        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            //服务器 配置
            bootstrap.group(bossGroup, workGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new WebsocketServerChannelInitializer())
                    .option(ChannelOption.SO_BACKLOG, 1024)  //配置TCP参数，握手字符串长度设置
                    .option(ChannelOption.TCP_NODELAY, true) //TCP_NODELAY算法，尽可能发送大块数据，减少充斥的小块数据
                    .childOption(ChannelOption.SO_KEEPALIVE, true)//开启心跳包活机制，就是客户端、服务端建立连接处于ESTABLISHED状态，超过2小时没有交流，机制会被启动
                    .childOption(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(592048))//配置固定长度接收缓存区分配器
            ;
            //绑定端口  开启事件驱动
            log.info("【服务器启动成功--------------端口：" + port + "】");
            Channel channel = bootstrap.bind(port).sync().channel();
            channel.closeFuture().sync();
        } catch (Exception e) {
            log.error("服务器启动失败，", e);
            throw new RuntimeException("服务器启动失败");
        } finally {
            //关闭资源
            bossGroup.shutdownGracefully();
            workGroup.shutdownGracefully();
        }
    }
    @PostConstruct()
    public void ServerInit(){
        new Thread(()-> { startServer();}).start();
    }
    @Value("${netty.server.port}")
    public Integer port;


    @Value("${netty.server.bossGroupSize}")
    public Integer bossGroupSize;

    @Value("${netty.server.workGroupSize}")
    public Integer workGroupSize;

    public Integer getPort() {
        return port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

    public Integer getBossGroupSize() {
        return bossGroupSize;
    }

    public void setBossGroupSize(Integer bossGroupSize) {
        this.bossGroupSize = bossGroupSize;
    }

    public Integer getWorkGroupSize() {
        return workGroupSize;
    }

    public void setWorkGroupSize(Integer workGroupSize) {
        this.workGroupSize = workGroupSize;
    }
}
